<template>
  <div class="m-iselect">
    <span class="name">按省份选择</span>
    <el-select
      v-model="pvalue"
      placeholder="请选择省份"
    >
      <el-option
        v-for="item in province"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      />
    </el-select>
    <el-select
      v-model="cvalue"
      :disabled="!pvalue"
      placeholder="请选择城市"
    >
      <el-option
        v-for="item in cities"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      />
    </el-select>
    <span
      class="name"
      style="margin-left: 50px"
    >直接搜索</span>
    <!-- 这个远程搜索组件的数据结构中 每一项一定要有value值 value是显示的内容 -->
    <el-autocomplete
      v-model="searchCity"
      :fetch-suggestions="querySearchAsync"
      placeholder="请输入内容"
      @select="handleSelect"
    />
  </div>
</template>
<script>
import _ from 'lodash'
export default {
  data() {
    return {
      pvalue: '',
      province: [],
      cvalue: '',
      cities: [],
      searchCity: '',
      allCities: [] //全国所有城市
    }
  },
  watch: {
    pvalue: async function(newValue, oldValue) {
      //关于watch 和method中的函数 官方文档中有解释
      //不可使用箭头函数定义 因为箭头函数的this绑定的是上下文中的this而不是调用者
      //箭头函数绑定了父级作用域的上下文，所以 this 将不会按照期望指向 Vue 实例，
      //this.updateAutocomplete 将是 undefined。
      //vue中的method watch 中的函数this指向vue实例。自动绑定到实例 使用箭头函数this会得到undefined
      let self = this
      //省份发生改变 根据省份请求当前城市
      if (!newValue) return
      let {
        status,
        data: { city }
      } = await self.$axios.get(`/geo/province/${newValue}`)
      this.cities = city.map(item => {
        return {
          value: item.id,
          label: item.name
        }
      })
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    async init() {
      let {
        status,
        data: { province }
      } = await this.$axios.get('/geo/province')
      this.province = province.map(item => {
        return {
          value: item.id,
          label: item.name
        }
      })
    },
    //element-ui规定的 用户输入内容的时候这个函数就会被响应
    //这个函数有两个参数 第一个参数为当前用户输入的内容 第二个参数为callback
    //callback一定要传入一个数组  且 这个数组中的每一项一定要有value属性
    //value属性就是在input显示的内容 且 也是el-autocomplete绑定的v-model值 在这个页面中也就是选中的searchCity
    //callback传入要显示的内容 他就会进行显示
    querySearchAsync: _.debounce(async function(query, cb) {
      //这个函数--- 先判读目前allcities是否保存当前所有城市的列表
      //从全国所有城市中筛选用户输入的query 符合条件的进行cb()调用 他就会把符合的显示在input下方
      if (!this.allCities.length) {
        //如果全国列表城市是空 先进行获取
        let {
          status,
          data: { city }
        } = await this.$axios.get('/geo/city')
        this.allCities = city.map(item => {
          return {
            //注意city的每一项数据中一定要具有value值 显示的就是每一项的value值
            value: item.name,
            id: item.id
          }
        })
        //获取所有之后在进行筛选
        //要进行显示的内容放在回调中
        cb(
          this.allCities.filter(item => {
            //满足过滤条件的返回一个数组传递给cb
            //return item.value.includes(query)
            return item.value.indexOf(query) > -1
          })
        )
      } else {
        //如果citys已经获取到了 直接执行筛选
        cb(
          //[Autocomplete]autocomplete suggestions must be an array
          //这个组件cb回来一定要传入一个数组 且数组中每一个元素必须包含value属性
          this.allCities.filter(item => {
            //满足过滤条件的返回一个数组传递给cb
            //return item.value.includes(query)
            return item.value.indexOf(query) > -1
          })
        )
      }
    }, 200),
    handleSelect() {
      //这个是当前用户点击的时候触发的事件
    }
  }
}
</script>
<style lang="scss">
@import '@/assets/css/changeCity/iselect.scss';
</style>